﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EventReminder.Common;
using System.Collections;

namespace EventReminder.Server
{
    abstract class AEventProcessor : IEventProcessor
    {
        protected IEventProcessor _next;
        EventTypes _handles;

        public virtual IEventProcessor NextLink
        {
            get { return _next; }
            set { _next = value; }
        }

        //public virtual EventTypes Handles { get { return _handles; } }

        // only allow setting thru inheriting instantiation
        protected AEventProcessor(EventTypes handles)
        {
            _handles = handles;
        }

        //public AEventProcessor(EventTypes handles, IEventProcessor nextInChain)
        //{
        //    _next = nextInChain;
        //    _handles = handles;
        //}

        public virtual void AddEvent(EventData data)
        {
            if (data.Type == _handles || _next == null)
            {
                ProcessAddEvent(data);
            }
            else
            {
                _next.AddEvent(data);
            }
        }

        protected abstract void ProcessAddEvent(EventData data);

        public virtual void ModifyEvent(EventData oldVersion, EventData newVersion)
        {
            // NOTE: will run into problems if old and new are different versions; ignore for now
            if (newVersion.Type == _handles || _next == null)
            {
                ProcessModifyEvent(oldVersion, newVersion);
            }
            else
            {
                _next.ModifyEvent(oldVersion, newVersion);
            }
        }

        protected abstract void ProcessModifyEvent(EventData oldVersion, EventData newVersion);

        public virtual void DeleteEvent(EventData data)
        {
            if (data.Type == _handles || _next == null)
            {
                ProcessDeleteEvent(data);
            }
            else
            {
                _next.DeleteEvent(data);
            }
        }

        protected abstract void ProcessDeleteEvent(EventData data);

        /// <summary>
        /// Returns an IEnumerator that allows iteration from this link in the chain to the bottom link.
        /// Does not go up!  If you want to start from the top of the chain, call this method from the
        /// top link.
        /// </summary>
        /// <returns></returns>
        public IEnumerator<IEventProcessor> GetEnumerator()
        {
            return new EventProcessorEnumerator(this);
        }

        /// <summary>
        /// Returns an IEnumerator that allows iteration from this link in the chain to the bottom link.
        /// Does not go up!  If you want to start from the top of the chain, call this method from the
        /// top link.
        /// </summary>
        /// <returns></returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
}
